package com.foreveross.crawl.adapter.sub.impl20140402.v3;

import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import com.foreveross.crawl.adapter.AbstractAdapter;
import com.foreveross.crawl.adapter.PlaneInfoEntityBuilder;
import com.foreveross.crawl.common.util.DateUtil;
import com.foreveross.crawl.common.util.RegHtmlUtil;
import com.foreveross.crawl.domain.airfreight.CabinEntity;
import com.foreveross.crawl.domain.airfreight.TransitEntity;
import com.foreveross.crawl.domain.airfreight.doub.CabinRelationEntity;
import com.foreveross.crawl.domain.airfreight.doub.DoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnCabinEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnDoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnTransitEntity;
import com.foreveross.taskservice.common.bean.TaskModel;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * 加拿大航空适配器
 * @author admin
*/
public class CanadaAdapter extends AbstractAdapter{

	private boolean IS_ONLY_FLIGHT=true;//是否只要直达
	
	private static Integer backCount=3;//抓取失败时回滚次数
	private static Integer sleepTime=60000;//从Amadues回滚之前休息一下	
	
	private static Integer VERSION=2;//版本控制
	
	
	private Map<String,String> countSessions_1=Maps.newHashMap();
	private Map<String,String> countSessions_2=Maps.newHashMap();
	private Map<String,String> idByPrice=Maps.newHashMap();//把对应的ID价格存入
	
	private Map<String ,Map<String,String>> priceByid_1=new HashMap<String, Map<String,String>>();//对应ID系列价格存
	private Map<String ,Map<String,String>> priceByid_2=new HashMap<String, Map<String,String>>();
	private List<String> getDatas=Lists.newArrayList();
	
	private Map<String,String> taxById=Maps.newHashMap();//对应第二层ID下的税总价
	private Map<String,String>FilterId=Maps.newHashMap();//存储过滤出的ID
	private String jsessionid;
	private List<String[]> priceList=Lists.newArrayList();
	
	public static Map<String,String> monthM=Maps.newHashMap();
	{
		monthM.put("一月", "01");
		monthM.put("二月", "02");
		monthM.put("三月", "03");
		monthM.put("四月", "04");
		monthM.put("五月", "05");
		monthM.put("六月", "06");
		monthM.put("七月", "07");
		monthM.put("八月", "08");
		monthM.put("九月", "09");
		monthM.put("十月", "10");
		monthM.put("十一月", "11");
		monthM.put("十二月", "12");
	}
	
	//舱位商品名
	public static Map<String,String>CabinByNum=Maps.newHashMap();
	{
		CabinByNum.put("0", "Tango");
		CabinByNum.put("1", "Flex");
		CabinByNum.put("2", "Latitude");
		CabinByNum.put("6", "商务舱（特价）");
		CabinByNum.put("7", "商务舱（全价）");
		
		//new
		CabinByNum.put("ECONOMY", "经济舱");
		CabinByNum.put("PREMIUM_ECONOMY", "豪华经济舱");
		CabinByNum.put("BUSINESS", "商务舱");		
	}
	
	public CanadaAdapter(TaskModel taskQueue) {
		super(taskQueue);
	}

	@Override
	public String getUrl() throws Exception {
		
		return null;
	}

	
	@Override
	public Object fetch(String url) throws Exception {
		switch (super.getRouteType()) {
		case INTERNATIONAL_ROUND:
			if(VERSION==2)return fetchDI_V2();else return fetchDI();//国际往返(做版本控制)
		}
		return null;
	}

	@Override
	public boolean validateFetch(Object fetchObject) throws Exception {
		return true;
	}

	@Override
	public List<Object> paraseToVo(Object obj) throws Exception {
		switch (super.getRouteType()) {
		case INTERNATIONAL_ROUND:
			if(VERSION==2)return paraseToVoDI(obj);else return paraseToVoDI_2(obj);//国际往返
		}
		return null;
	}
	
	
	/**
	 * 国际URL 往返
	*/
	//新版
	public Object fetchDI_V2() throws Exception {
		Object objs=null;
		HttpClient httpClient = this.getHttpClient();
		HttpGet g = new HttpGet(F_URL());
		HttpPost httpPost = null;
		setRequestHeadInfo(g);
		String page1=null,page2=null;
		try{
			logger.info("获取数据，并解析成JSON...");
			page1= excuteRequest(httpClient, g, "gb2312");
			//解析成Json
			if(page1.toString()==null || "".equals(page1) || page1.length()<100 || !page1.contains("var availResponseJson")){
				//回滚
				while(backCount-->0){
					objs=fetchDI();
				}
			}
			if(page1.contains("var availResponseJson")){
				logger.info("解析成功！");
				objs=RegHtmlUtil.regStr(page1,"var\\s*availResponseJson\\s*=\\s*(.*\\}}])");
//				System.out.println(objs);
			}else{
				logger.error("解析失败！");
			}
			
		}catch (Exception e) {
			e.printStackTrace();
		}
		super.setLenghtCount(objs.toString().length());
		super.appendPageContents(objs.toString());
		return objs;
	}
	
	
	//旧版
	public Object fetchDI() throws Exception {
		//取第一层数据
		List<String> objs=Lists.newArrayList();
		HttpClient httpClient = this.getHttpClient();
		HttpGet g = new HttpGet(F_URL());
		HttpPost httpPost = null;
		setRequestHeadInfo(g);
		String page1=null,page2=null;
		try{
			logger.info("获取第一层数据，并解析此次的jsessionid...");
			page1= excuteRequest(httpClient, g, "gb2312");
			if(page1 !=null){
				T_page_Id(page1);
				T_page_Index(page1,countSessions_1,priceByid_1);
			}
			
			logger.info("第一层数据解析完成；进入第二层解析并处理对应的数据....");
			if(countSessions_1.size()>0){
				for(Map.Entry<String, String> map:countSessions_1.entrySet()){
					String id=map.getKey();
					String indexCs=map.getValue();
					httpPost=new HttpPost(S_URL(indexCs.split("/")[0],indexCs.split("/")[1],id));
					setPostHeadInfo(httpPost,F_URL());
					page2=excuteRequest(httpClient, httpPost, "UTF-8");
					if(page2 !=null ){
						logger.info("第二层数据获取成功，开始解析数据...");
						T_page_Index(page2,countSessions_2,priceByid_2);
						getTaxs(page2);
					}
					if(countSessions_2.size()>0){ 
						logger.info("第二层解析完成!");
						break;
					}
				}
				
				
				
				if(priceByid_1.size()>0 && priceByid_2.size()>0){
					logger.info("解析第三层数据...");
					String result="";
					int i=0;
					for(Map.Entry<String, Map<String,String>> maps:priceByid_1.entrySet()){
						i++;
						String id_1=maps.getKey();//系列号1
						String idSession_1=null;
						String index_1=null;
						String count_1=null;
						
						for(Map.Entry<String, String> mapSeId_1:countSessions_1.entrySet()){
							if(mapSeId_1.getKey().substring(0,mapSeId_1.getKey().length()-3).equals(id_1) && idByPrice.get(mapSeId_1.getKey())!=null){
								idSession_1=mapSeId_1.getKey();
								index_1=mapSeId_1.getValue().split("/")[0];
								count_1=mapSeId_1.getValue().split("/")[1];
								break;
							}
						}
						
						
						int j=0;
						for(Map.Entry<String, Map<String,String>> map2:priceByid_2.entrySet()){
							j++;
							
							//*****************************************************************
							//仅用于开发测试
							/*if(j==3){
								break;
							}*/
							//*****************************************************************
							
							String id_2=map2.getKey();//系列号2
							getDatas.add(id_1+"-"+id_2);
							String idSession_2=null;
							
							String index_2=null;
							String count_2=null;
							
							for(Map.Entry<String, String> mapSeId_2:countSessions_2.entrySet()){
								if(mapSeId_2.getKey().substring(0,mapSeId_2.getKey().length()-3).equals(id_2) && idByPrice.get(mapSeId_2.getKey()) !=null){
									idSession_2=mapSeId_2.getKey();
									index_2=mapSeId_2.getValue().split("/")[0];
									count_2=mapSeId_2.getValue().split("/")[1];
									break;
								}
							}
							
							
							httpPost=new HttpPost(T_URL(idSession_1,idSession_2,index_1,count_1,index_2,count_2));
							setPostHeadInfo(httpPost,"http://book.aircanada.com/pl/AConline/en/FlexPricerAvailabilityServlet;jsessionid="+jsessionid);
							result=excuteRequest(httpClient, httpPost, "UTF-8");
							if(result.contains(".*会话超时.*")){
								logger.info("会话操作超时,重新获取jsessionid...");
								jsessionid="";
								HttpGet g_r = new HttpGet(F_URL());
								T_page_Id(excuteRequest(httpClient, g_r, "gb2312"));
								if(jsessionid !=null && !jsessionid.equals("")){
									logger.info("重新获取jsessionid成功！");
								}
								continue;
							}
							logger.info(String.format("数据获取成功【%s/%s-%s/%s】", i,priceByid_1.size(),j,priceByid_2.size()));
							if(result !=null && !result.equals("")){
								String price[]=new String[2];
								price[0]=idByPrice.get(idSession_1);
								price[1]=idByPrice.get(idSession_2);
								priceList.add(price);
								objs.add(result);
							}
						}
						//*****************************************************************
						//仅用于开发测试
						/*if(i==4){
							break;
						}*/
						//*****************************************************************
					}
				}
			}
			
			if(objs.size()>0) {//保存源文件镜像和大小
				super.setLenghtCount(objs.toString().length());
				String sources="";
				for(String s:objs){
					sources+=s;
				}
				super.appendPageContents(sources);
			}
		}catch (Exception e) {
			e.getMessage();
		}
		
		return objs;
	}
	
	/**
	 * 排除非直达信息
	*/
	public boolean T_Flight(String page){
		boolean flag =false;
		if(page !=null && page.contains("rowspan=\"1\"")){
			List<String> fil=Lists.newArrayList();
			fil=getPatternList(page,"<td\\s*rowspan=\"1\"\\s*class=\"\\w*\\W*\"\\s*id=\"(\\w*)_sep\"", " ", "");
			if(fil.size()>0){
				for(int i=0;i<fil.size();i++){
					FilterId.put(fil.get(i), i+"");
				}
				if(FilterId.size()>0) flag=true;
			}
			
		}
		return flag;
	}
	
	public boolean T_id(Map<String,String> map,String id){
		boolean fl=false;
		if(map.size()>0){
			for(Map.Entry<String, String> mapid:map.entrySet())
				if(mapid.getKey().equals(id)) {
					fl=true;
					break;
				}
		}
		return fl;
	}
	
	/**
	 * 设置请求头信息
	 * 
	 * @param g
	 */
	private void setRequestHeadInfo(HttpRequestBase g) {
		g.setHeader("Host", "book.aircanada.com");
		g.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0");
		g.setHeader("Accept","	text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
		g.setHeader("Referer", "http://www.aircanada.com/zh/home.html");
		g.setHeader("Accept-Language", "zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3");
	}
	
	private void setPostHeadInfo(HttpPost httpPost,String postUrl) {
		httpPost.setHeader("Host", "book.aircanada.com");
		httpPost.setHeader("User-Agent","	Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0");
		httpPost.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
		httpPost.setHeader("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
		httpPost.setHeader("Referer",postUrl);
	}
	
	
	//国际往返第一层URL
	public String F_URL(){
		StringBuffer url =new StringBuffer("http://book.aircanada.com/pl/AConline/en/OverrideServlet?");
		url.append("ARRANGE_BY=N");
		url.append("&");
		url.append("AUTHORIZATION_ID=");
		url.append("&");
		url.append("BOOKING_FLOW=INTERNATIONAL");
		url.append("&");
		url.append("B_ANY_TIME_1=TRUE");
		url.append("&");
		url.append("B_ANY_TIME_2=TRUE");
		url.append("&");
		url.append("B_DATE_1="+taskQueue.getFlightDate().replaceAll("-", "")+"0000");
		url.append("&");
		url.append("B_DATE_2="+taskQueue.getReturnGrabDate().replaceAll("-", "")+"0000");
		url.append("&");
		url.append("B_LOCATION_1="+taskQueue.getFromCity());
		url.append("&");
		url.append("B_LOCATION_2="+taskQueue.getToCity());
		url.append("&");
		url.append("CERTIFICATE_NUMBER=");
		url.append("&");
		url.append("COMMERCIAL_FARE_FAMILY_1=FLEXIWDREV");
		url.append("&");
		url.append("COMMERCIAL_FARE_FAMILY_2=CRTPREMIUM");
		url.append("&");
		url.append("COMMERCIAL_FARE_FAMILY_3=");
		url.append("&");
		url.append("CORPORATE_NUMBER_1=");
		url.append("&");
		url.append("CORPORATE_NUMBER_2=");
		url.append("&");
		url.append("COUNTRY=CA");
		url.append("&");
		url.append("CUSTOM_AUTH_ID=");
		url.append("&");
		url.append("DATE_RANGE_QUALIFIER_1=C");
		url.append("&");
		url.append("DATE_RANGE_QUALIFIER_2=C");
		url.append("&");
		url.append("DATE_RANGE_VALUE_1=0");
		url.append("&");
		url.append("DATE_RANGE_VALUE_2=0");
		url.append("&");
		url.append("DIRECT_NON_STOP=FALSE");
		url.append("&");
		url.append("DISPLAY_TYPE=3");
		url.append("&");
		url.append("EMBEDDED_TRANSACTION=FlexPricerAvailabilityServlet");
		url.append("&");
		url.append("EXTERNAL_ID=GUEST");
		url.append("&");
		url.append("E_LOCATION_1="+taskQueue.getToCity());
		url.append("&");
		url.append("E_LOCATION_2="+taskQueue.getFromCity());
		url.append("&");
		url.append("FFMILES=");
		url.append("&");
		url.append("FNAME=");
		url.append("&");
		url.append("HAS_INFANT_1=FALSE");
		url.append("&");
		url.append("HAS_INFANT_2=");
		url.append("&");
		url.append("HAS_INFANT_3=");
		url.append("&");
		url.append("HAS_INFANT_4=");
		url.append("&");
		url.append("HAS_INFANT_5=");
		url.append("&");
		url.append("HAS_INFANT_6=");
		url.append("&");
		url.append("HAS_INFANT_7=");
		url.append("&");
		url.append("HAS_INFANT_8=");
		url.append("&");
		url.append("HAS_INFANT_9=");
		url.append("&");
		url.append("IATA_AGENT_FIRST_NAME=");
		url.append("&");
		url.append("IATA_AGENT_ID_NUMBER=");
		url.append("&");
		url.append("IATA_AGENT_LAST_NAME=");
		url.append("&");
		url.append("IS_YOUTH_1=FALSE");
		url.append("&");
		url.append("IS_YOUTH_2=");
		url.append("&");
		url.append("IS_YOUTH_3=");
		url.append("&");
		url.append("IS_YOUTH_4=");
		url.append("&");
		url.append("IS_YOUTH_5=");
		url.append("&");
		url.append("IS_YOUTH_6=");
		url.append("&");
		url.append("IS_YOUTH_7=");
		url.append("&");
		url.append("IS_YOUTH_8=");
		url.append("&");
		url.append("IS_YOUTH_9=");
		url.append("&");
		url.append("LANGUAGE=ZH");
		url.append("&");
		url.append("LNAME=");
		url.append("&");
		url.append("MARKET=CN");
		url.append("&");
		url.append("MNAME=");
		url.append("&");
		url.append("NTP_AUTHORIZATION=true");
		url.append("&");
		url.append("PRICING_TYPE=I");
		url.append("&");
		url.append("PRIVATE_LABEL=ACO_AC_AIR");
		url.append("&");
		url.append("SELECTED_TIER_STATUS=");
		url.append("&");
		url.append("SEVEN_DAY_SEARCH=FALSE");
		url.append("&");
		url.append("SITE=SAADSAAD");
		url.append("&");
		url.append("SO_SITE_COUNTRY_OF_RESIDENCE=CN");
		url.append("&");
		url.append("SO_SITE_EDITION=CA");
		url.append("&");
		url.append("SO_SITE_FP_WITHHOLD_SURCHARG=TRUE");
		url.append("&");
		url.append("SO_SITE_POINT_OF_SALE="+taskQueue.getFromCity());
		url.append("&");
		url.append("SO_SITE_POINT_OF_TICKETING="+taskQueue.getFromCity());
		url.append("&");
		url.append("SO_SITE_REST_AIRLINES_LST=AC");
		url.append("&");
		url.append("SO_SITE_SKIP_FLIFO=FALSE");
		url.append("&");
		url.append("TITLE=");
		url.append("&");
		url.append("TRAVELLER_TYPE_1=ADT");
		url.append("&");
		url.append("TRAVELLER_TYPE_2=");
		url.append("&");
		url.append("TRAVELLER_TYPE_3=");
		url.append("&");
		url.append("TRAVELLER_TYPE_4=");
		url.append("&");
		url.append("TRAVELLER_TYPE_5=");
		url.append("&");
		url.append("TRAVELLER_TYPE_6=");
		url.append("&");
		url.append("TRAVELLER_TYPE_7=");
		url.append("&");
		url.append("TRAVELLER_TYPE_8=");
		url.append("&");
		url.append("TRAVELLER_TYPE_9=");
		url.append("&");
		url.append("TRAVEL_AGENT_PNR=");
		url.append("&");
		url.append("TRIP_FLOW=YES");
		url.append("&");
		url.append("TRIP_TYPE=R");
		url.append("&");
		url.append("TYPE_OF_CORPORATE_FARE=");
		url.append("&");
		url.append("USERID=GUEST");
		url.append("&");
		url.append("USER_TIER_STATUS_CODE=");
		url.append("&");
		url.append("searchType=");			
		
		return url.toString();
	}
	
	//国际往返第二层URL
	public String S_URL(String index,String count,String id){
		StringBuffer url=new StringBuffer("http://book.aircanada.com/pl/AConline/en/FlexPricerAvailabilityServlet;jsessionid="+jsessionid+"?");
		url.append("BOUND_ID=INBOUND");
		url.append("&");
		url.append("B_DATE_1="+taskQueue.getFlightDate().replaceAll("-", "")+"0000");
		url.append("&");
		url.append("B_DATE_2="+taskQueue.getReturnGrabDate().replaceAll("-", "")+"0000");
		url.append("&");
		url.append("B_LOCATION_1="+taskQueue.getFromCity());
		url.append("&");
		url.append("B_LOCATION_2="+taskQueue.getToCity());
		url.append("&");
		url.append("COMMERCIAL_FARE_FAMILY_1=FLEXIWDREV");
		url.append("&");
		url.append("COMMERCIAL_FARE_FAMILY_2=CRTPREMIUM");
		url.append("&");
		url.append("COMMERCIAL_FARE_FAMILY_3=");
		url.append("&");
		url.append("CORPORATE_NUMBER_1=");
		url.append("&");
		url.append("CORPORATE_NUMBER_2=");
		url.append("&");
		url.append("CURRENT_TIME_WARNING_MESSAGE_1=");
		url.append("&");
		url.append("CURRENT_TRAFFIC_WARNING_MESSAGE_1=");
		url.append("&");
		url.append("CURRENT_TRAFFIC_WARNING_MESSAGE_2=");
		url.append("&");
		url.append("CURRENT_TIME_WARNING_MESSAGE_2=");
		url.append("&");
		url.append("CURRENT_TRAFFIC_XM_MESSAGE_2=");
		url.append("&");
		url.append("CURRENT_WARNING_MESSAGE_1=");
		url.append("&");
		url.append("CURRENT_WARNING_MESSAGE_2=");
		url.append("&");
		url.append("DISPLAY_ALL_PRICE=");
		url.append("&");
		url.append("DISPLAY_TYPE=3");
		url.append("&");
		url.append("E_LOCATION_1="+taskQueue.getToCity());
		url.append("&");
		url.append("E_LOCATION_2="+taskQueue.getFromCity());
		url.append("&");
		url.append("FLIGHT_CSSID_1="+id);
		url.append("&");
		url.append("FLIGHT_CSSID_2=");
		url.append("&");
		url.append("FLIGHT_ID_1="+index);
		url.append("&");
		url.append("FLIGHT_ID_2=");
		url.append("&");
		url.append("FLIGHT_UPSELL_FOR_CSSID_1=");
		url.append("&");
		url.append("FLIGHT_UPSELL_FOR_CSSID_2=");
		url.append("&");
		url.append("FLOW_BOOKING_TYPE=BOOK");
		url.append("&");
		url.append("FROM_AVAIL=true");
		url.append("&");
		url.append("FROM_AVAIL_SHOW_FAREPAGE=true");
		url.append("&");
		url.append("FROM_CALENDAR=");
		url.append("&");
		url.append("FROM_FFPO=true");
		url.append("&");
		url.append("FROM_FFPO=true");
		url.append("&");
		url.append("HAS_INFANT_1=FALSE");
		url.append("&");
		url.append("HAS_INFANT_2=");
		url.append("&");
		url.append("HAS_INFANT_3=");
		url.append("&");
		url.append("HAS_INFANT_4=");
		url.append("&");
		url.append("HAS_INFANT_5=");
		url.append("&");
		url.append("HAS_INFANT_6=");
		url.append("&");
		url.append("HAS_INFANT_7=");
		url.append("&");
		url.append("HAS_INFANT_8=");
		url.append("&");
		url.append("HAS_INFANT_9=");
		url.append("&");
		url.append("HIDDEN_PANEL=");
		url.append("&");
		url.append("IS_UPSELL_PRICE_SELECTED=");
		url.append("&");
		url.append("IS_YOUTH_1=FALSE");
		url.append("&");
		url.append("LANGUAGE=ZH");
		url.append("&");
		url.append("LINE_1="+index+URLEncoder.encode("/")+count);
		url.append("&");
		url.append("MATRICE_PRICE=");
		url.append("&");
		url.append("MATRICE_PRICE_CONVERTED=");
		url.append("&");
		url.append("MATRICE_PRICE_FLOAT=");
		url.append("&");
		url.append("MATRICE_PRICE_FLOAT_CONVERTED=");
		url.append("&");
		url.append("OUTBOUND_FLIGHT_ID=");
		url.append("&");
		url.append("OUTBOUND_RECOMMENDATION_ID=");
		url.append("&");
		url.append("PAGE_TICKET=0");
		url.append("&");
		url.append("PRICING_TYPE=I");
		url.append("&");
		url.append("PROMOTION_CABIN=");
		url.append("&");
		url.append("PROPOSE_BUYUP=true");
		url.append("&");
		url.append("PROPOSE_OPTION=true");
		url.append("&");
		url.append("RECOMMENDATION_ID_1="+count);
		url.append("&");
		url.append("RECOMMENDATION_ID_2=");
		url.append("&");
		url.append("RELOAD_BOUND=");
		url.append("&");
		url.append("RELOAD_FFPO=");
		url.append("&");
		url.append("SITE=SACSSACS");
		url.append("&");
		url.append("TRAVELLER_TYPE_1=ADT");
		url.append("&");
		url.append("TRAVELLER_TYPE_2=");
		url.append("&");
		url.append("TRAVELLER_TYPE_3=");
		url.append("&");
		url.append("TRAVELLER_TYPE_4=");
		url.append("&");
		url.append("TRAVELLER_TYPE_5=");
		url.append("&");
		url.append("TRAVELLER_TYPE_6=");
		url.append("&");
		url.append("TRAVELLER_TYPE_7=");
		url.append("&");
		url.append("TRAVELLER_TYPE_8=");
		url.append("&");
		url.append("TRAVELLER_TYPE_9=");
		url.append("&");
		url.append("TRIP_TYPE=R");
		url.append("&");
		url.append("TYPE_OF_FARE=");
		url.append("&");
		url.append("VISIBLE_PANEL=");
		
		return url.toString();
	}
	
	
	//第三层(最后一层)URL
	public String T_URL(String id_1,String id_2,String index_1,String count_1,String index_2,String count_2){
		StringBuffer url=new StringBuffer("http://book.aircanada.com/pl/AConline/en/FareServlet;jsessionid="+jsessionid+"?");
		url.append("B_DATE_1="+taskQueue.getFlightDate().replaceAll("-", "")+"0000");
		url.append("&");
		url.append("B_DATE_2="+taskQueue.getReturnGrabDate().replaceAll("-", "")+"0000");
		url.append("&");
		url.append("B_LOCATION_1="+taskQueue.getFromCity());
		url.append("&");
		url.append("B_LOCATION_2="+taskQueue.getToCity());
		url.append("&");
		url.append("COMMERCIAL_FARE_FAMILY_1=FLEXIWDREV");
		url.append("&");
		url.append("COMMERCIAL_FARE_FAMILY_2=CRTPREMIUM");
		url.append("&");
		url.append("COMMERCIAL_FARE_FAMILY_3=");
		url.append("&");
		url.append("CORPORATE_NUMBER_1=");
		url.append("&");
		url.append("CORPORATE_NUMBER_2=");
		url.append("&");
		url.append("CURRENT_TIME_WARNING_MESSAGE_1=");
		url.append("&");
		url.append("CURRENT_TIME_WARNING_MESSAGE_2=timeWarningPA1FL5");
		url.append("&");
		url.append("CURRENT_TRAFFIC_WARNING_MESSAGE_1=");
		url.append("&");
		url.append("CURRENT_TRAFFIC_WARNING_MESSAGE_2=");
		url.append("&");
		url.append("CURRENT_TRAFFIC_XM_MESSAGE_2=");
		url.append("&");
		url.append("CURRENT_WARNING_MESSAGE_1=warningPA0FL1FF6");
		url.append("&");
		url.append("CURRENT_WARNING_MESSAGE_2=");
		url.append("&");
		url.append("DISPLAY_ALL_PRICE=");
		url.append("&");
		url.append("DISPLAY_TYPE=3");
		url.append("&");
		url.append("E_LOCATION_1="+taskQueue.getToCity());
		url.append("&");
		url.append("E_LOCATION_2="+taskQueue.getFromCity());
		url.append("&");
		url.append("FLIGHT_CSSID_1="+id_1);
		url.append("&");
		url.append("FLIGHT_CSSID_2="+id_2);
		url.append("&");
		url.append("FLIGHT_ID_1=0");
		url.append("&");
		url.append("FLIGHT_ID_2="+index_2);
		url.append("&");
		url.append("FLIGHT_UPSELL_FOR_CSSID_1=");
		url.append("&");
		url.append("FLIGHT_UPSELL_FOR_CSSID_2=");
		url.append("&");
		url.append("FLOW_BOOKING_TYPE=BOOK");
		url.append("&");
		url.append("FROM_AVAIL=true");
		url.append("&");
		url.append("FROM_AVAIL_SHOW_FAREPAGE=true");
		url.append("&");
		url.append("FROM_CALENDAR=");
		url.append("&");
		url.append("FROM_FFPO=true");
		url.append("&");
		url.append("FROM_FFPO=true");
		url.append("&");
		url.append("HAS_INFANT_1=FALSE");
		url.append("&");
		url.append("HAS_INFANT_2=");
		url.append("&");
		url.append("HAS_INFANT_3=");
		url.append("&");
		url.append("HAS_INFANT_4=");
		url.append("&");
		url.append("HAS_INFANT_5=");
		url.append("&");
		url.append("HAS_INFANT_6=");
		url.append("&");
		url.append("HAS_INFANT_7=");
		url.append("&");
		url.append("HAS_INFANT_8=");
		url.append("&");
		url.append("HAS_INFANT_9=");
		url.append("&");
		url.append("HIDDEN_PANEL=");
		url.append("&");
		url.append("IS_UPSELL_PRICE_SELECTED=");
		url.append("&");
		url.append("IS_YOUTH_1=FALSE");
		url.append("&");
		url.append("LANGUAGE=ZH");
		url.append("&");
		url.append("LINE_2="+index_2+URLEncoder.encode("/")+count_2);
		url.append("&");
		url.append("MATRICE_PRICE=");
		url.append("&");
		url.append("MATRICE_PRICE_CONVERTED=");
		url.append("&");
		url.append("MATRICE_PRICE_FLOAT=");
		url.append("&");
		url.append("MATRICE_PRICE_FLOAT_CONVERTED=");
		url.append("&");
		url.append("OUTBOUND_FLIGHT_ID="+index_1);
		url.append("&");
		url.append("OUTBOUND_RECOMMENDATION_ID="+count_1);
		url.append("&");
		url.append("PAGE_TICKET=1");
		url.append("&");
		url.append("PRICING_TYPE=I");
		url.append("&");
		url.append("PROMOTION_CABIN=");
		url.append("&");
		url.append("PROPOSE_BUYUP=true");
		url.append("&");
		url.append("PROPOSE_OPTION=true");
		url.append("&");
		url.append("RECOMMENDATION_ID_1="+count_2);
		url.append("&");
		url.append("RECOMMENDATION_ID_2=");
		url.append("&");
		url.append("RELOAD_BOUND=");
		url.append("&");
		url.append("RELOAD_FFPO=");
		url.append("&");
		url.append("SITE=SACSSACS");
		url.append("&");
		url.append("TRAVELLER_TYPE_1=ADT");
		url.append("&");
		url.append("TRAVELLER_TYPE_2=");
		url.append("&");
		url.append("TRAVELLER_TYPE_3=");
		url.append("&");
		url.append("TRAVELLER_TYPE_3=");
		url.append("&");
		url.append("TRAVELLER_TYPE_4=");
		url.append("&");
		url.append("TRAVELLER_TYPE_5=");
		url.append("&");
		url.append("TRAVELLER_TYPE_6=");
		url.append("&");
		url.append("TRAVELLER_TYPE_7=");
		url.append("&");
		url.append("TRAVELLER_TYPE_8=");
		url.append("&");
		url.append("TRAVELLER_TYPE_9=");
		url.append("&");
		url.append("TRIP_TYPE=R");
		url.append("&");
		url.append("TYPE_OF_FARE=");
		url.append("&");
		url.append("VISIBLE_PANEL=");
		
		return url.toString();
	}
	
	
	/**
	 * //解析第一层数据
	 */	
	//解析jsessionid
	public void T_page_Id(String page){
		if(page !=null && page.contains("jsessionid")){
			//解释出jsessionid
			jsessionid=RegHtmlUtil.regStr(page,"jsessionid=(\\s*\\S*)").replaceAll("\'", "").replaceAll("\"", "").replaceAll(";", "");
		}
	}
	
	//解析index/count,存入Map
	public void T_page_Index(String page,Map<String,String> map,Map<String ,Map<String,String>> map_data){
		if(page !=null){
			//排除不是直达的
			if(T_Flight(page)){
			
				String key="FFPOBuilder.addBoundedFlight\\((\\s*\\S*)\\)";
				List<String> allIndex=Lists.newArrayList();
				allIndex=getPatternList(page.replaceAll(" ", ""),key," ","");//System.out.println(page);
				if(allIndex.size()>0){
					for(String data:allIndex){
						String[]a=data.split("\\,");
						String id=a[2].replaceAll("\\'", "");
						if( !T_id(FilterId,id)&& IS_ONLY_FLIGHT) continue;
						String index=a[3].replaceAll("\\'", "");
						String count=a[6].replaceAll("\\'", "");
						String price=a[8];
						map.put(id, index+"/"+count);
						idByPrice.put(id, price);
						if(map_data.get(id.subSequence(0, id.length()-3))!=null){
							map_data.get(id.subSequence(0,id.length()-3)).put(id, price);
						}else{
							Map<String,String> getIdPri=Maps.newHashMap();
							getIdPri.put(id, price);
							map_data.put(id.substring(0,id.length()-3), getIdPri);
						}
					}
				}
			}
		}
	}
	
	/*
	 * 获取往返程税收
	*/
	public void getTaxs(String page){
		if(page !=null){//taxById
			String key="FFPOBuilder.setPieBoundedFlightPrice\\((\\s*\\S*)\\)";
			List<String> allIndex=Lists.newArrayList();
			allIndex=getPatternList(page.replaceAll(" ", ""),key," ","");//System.out.println(page);
			if(allIndex.size()>0){
				for(String data:allIndex){
					String[]a=data.split("\\,");
					String id=a[1];
					double price_1=a[7] !=null?Double.parseDouble(a[7]):0.0;
					double price_2=a[9] !=null?Double.parseDouble(a[9]):0.0;
					taxById.put(id, price_1+price_2+"");
				}
			}
			
		}
	}
	
	
	private List<String> getPatternList(String content, String regEx, String replace, String replacement){
		Pattern p=Pattern.compile(regEx, Pattern.DOTALL|Pattern.MULTILINE);
		Matcher m=p.matcher(content);
		List<String> strList = new ArrayList<String>();
		while(m.find()){
			strList.add(m.group(1).trim().replaceAll(replace, replacement));
		}
		return strList;
	}
	/**
	 * 国际往返适配器
	 * 
	 */	
	//新版
	private List<Object> paraseToVoDI(Object fetchObject) throws Exception {
		List<Object> dataList = new ArrayList<Object>();
		
		try{
			JSONArray obj = JSONArray.fromObject(fetchObject);
			if(obj.size()==2){//有回程和去程
				JSONObject goData=obj.getJSONObject(0);//去程信息
				JSONObject reData=obj.getJSONObject(1);//回程信息
				Set<CabinRelationEntity>cabinRelationEntitys=new HashSet<CabinRelationEntity>();//舱位关系 
				JSONArray gResult=goData.getJSONArray("results");//去程List
				JSONArray rResult=reData.getJSONArray("results");//回程List
				if(gResult.size()>0){
				
					for(int i=0;i<gResult.size();i++){//一段去程对应多段回程
						Map<String,String[]> GpriceList=new HashMap<String, String[]>();//去程价格总信息
						Double gTotalHightPrice=0d ,gTotalLowestPrice=0d,gNakeHightPrice,gNakeLowestPrice,gTaxHightPrice,gTaxLowestPrice;
						Double rTotalHightPrice=0d ,rTotalLowestPrice=0d,rNakeHightPrice,rNakeLowestPrice,rTaxHightPrice,rTaxLowestPrice;
						DoublePlaneInfoEntity entity=null;
						JSONObject result=gResult.getJSONObject(i);
						List<FlightInfo> gInfos=(List<FlightInfo>) trLegInfo(result).get(0);//去程航班基本信息
						List<CabinInfo>  gCanbinInfos= (List<CabinInfo>) trLegInfo(result).get(1);//去程舱位价格信息
						rPrices(gCanbinInfos, GpriceList);
						//价格排序
						List<String> gPriceSort =new ArrayList<String>();
						if(GpriceList.size()>0){
							gPriceSort=mapCompare(GpriceList);
						}
						entity=PlaneInfoEntityBuilder.buildPlaneInfo(
								taskQueue, "AC","加拿大航空","加拿大航空公司", gInfos.get(0).getStartTime(), gInfos.get(gInfos.size()-1).getStartTime(), gInfos.get(0).getFlightNo(), null, null, null, gInfos.get(0).getFlightType(),DoublePlaneInfoEntity.class);
						entity.setFlightDuration(gInfos.get(0).getFlightDuration());
						entity.setCurrency("CNY");
						if(gInfos.size()>1){//说明去程有中转
							//组装去程中转
							for(FlightInfo gT:gInfos){
								TransitEntity trEntity=null;//去程中转
								trEntity=PlaneInfoEntityBuilder.buildTransitEntity(
										gT.getFlightNo(), null, "AC", "加拿大航", "加拿大航空公司", 
										gT.getFromAirport(), gT.getFromAirportName(), gT.getToAirport(), gT.getToAirportName(), gT.getFlightType(),TransitEntity.class);
								trEntity.setStartTime(com.foreveross.crawl.util.DateUtil.string2Date(gT.getStartTime(), "yyyy-MM-dd HH:mm:ss"));
								trEntity.setEndTime(com.foreveross.crawl.util.DateUtil.string2Date(gT.getEndTime(), "yyyy-MM-dd HH:mm:ss"));
								if(gT.getFlightDuration()!=null){
									entity.setFlightDuration(gT.getFlightDuration());
								}
								entity.getTransits().add(trEntity);//增加中转信息到中转实体中
							}
							
							//去程舱位信息
							if(gCanbinInfos.size()>0){
								for(CabinInfo GcanbinInfo:gCanbinInfos){
									String canbinClass=GcanbinInfo.getCabinClass();
									String totalPrice=GcanbinInfo.getTotalPrice()+"";
									String nakePrice=GcanbinInfo.getNakePirce()+"";
									String taxPrice=GcanbinInfo.getTaxPrice()+"";
									CabinEntity gCabE=PlaneInfoEntityBuilder.buildCabinInfo(canbinClass, null, null, taxPrice, nakePrice, totalPrice,null,null, CabinEntity.class);
									entity.getCabins().add(gCabE);
								}
								
							}
						}
						//回程
						for(int j=0;j<rResult.size();j++){//多段回程
							ReturnDoublePlaneInfoEntity rEntity=null;//回程实体
							List<FlightInfo> rInfos=(List<FlightInfo>) trLegInfo(rResult.getJSONObject(j)).get(0);//回程航班基本信息
							List<CabinInfo>  rCanbinInfos= (List<CabinInfo>) trLegInfo(rResult.getJSONObject(j)).get(1);//回程舱位价格信息
							Map<String,String[]> RpriceList=new HashMap<String, String[]>();//回程价格总信息
							rPrices(rCanbinInfos, RpriceList);
							//价格排序
							List<String>rPriceSort =new ArrayList<String>();
							if(RpriceList.size()>0){
								rPriceSort=mapCompare(RpriceList);
							}
							
							if(rInfos.size()>0){
								rEntity=PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, "AC", "加拿大航", "加拿大航空公司", rInfos.get(0).getTstartTime(), rInfos.get(0).getTendTime(), rInfos.get(0).getFlightNo(), null, rInfos.get(0).getAgentName(), null, rInfos.get(0).getFlightType(),ReturnDoublePlaneInfoEntity.class);
								if(rInfos.size()>1){//说明回程有中转
									for(FlightInfo rT:rInfos){
										ReturnTransitEntity reTrEntity=null;//回程中转
										reTrEntity=PlaneInfoEntityBuilder.buildReturnTransitEntity(rT.getFlightNo(), null,"AC", "加拿大航", "加拿大航空公司", rT.getFromAirport(), rT.getFromAirportName(), rT.getToAirport(), rT.getToAirportName(), rT.getFlightType());
										reTrEntity.setStartTime(com.foreveross.crawl.util.DateUtil.string2Date(rT.getStartTime(), "yyyy-MM-dd HH:mm:ss"));
										reTrEntity.setEndTime(com.foreveross.crawl.util.DateUtil.string2Date(rT.getEndTime(), "yyyy-MM-dd HH:mm:ss"));
										if(rT.getFlightDuration()!=null){
											entity.setFlightDuration(rT.getFlightDuration());
										}
										rEntity.getReturnTransits().add(reTrEntity);
									}
								}
								//处理回程舱位信息
								if(rCanbinInfos.size()>0){
									
									for(CabinInfo RcanbinInfo:rCanbinInfos){
										String canbinClass=RcanbinInfo.getCabinClass();
										Double totalPrice=RcanbinInfo.getTotalPrice();
										Double nakePrice=RcanbinInfo.getNakePirce();
										Double taxPrice=RcanbinInfo.getTaxPrice();
										ReturnCabinEntity rCabinE=PlaneInfoEntityBuilder.buildCabinInfo(canbinClass, null, null, taxPrice+"", nakePrice+"", totalPrice+"", null,null, ReturnCabinEntity.class);
										rEntity.getReturnCabins().add(rCabinE);
										
										//舱位关系 
										for(CabinEntity ce:entity.getCabins()){
											CabinRelationEntity cabinRelationEntity=new CabinRelationEntity();
											cabinRelationEntity.setCabinId(ce.getId());
											cabinRelationEntity.setFullPrice(ce.getPrice()+nakePrice);
											cabinRelationEntity.setReturnCabinId(rCabinE.getId());
											cabinRelationEntity.setTaxesPrice(ce.getTaxesPrice()+taxPrice);
											cabinRelationEntity.setTotalFullPrice(ce.getOriginalPrice()+totalPrice);
											cabinRelationEntitys.add(cabinRelationEntity);
										}
									}
								}
								//每一段回程最高最低
								rEntity.setTotalHighestPrice(Double.parseDouble(RpriceList.get(rPriceSort.get(0))[0]!=null?RpriceList.get(rPriceSort.get(0))[0]:"0.0"));
								rEntity.setTotalLowestPrice(Double.parseDouble(RpriceList.get(rPriceSort.get(rPriceSort.size()-1))[0]!=null?RpriceList.get(rPriceSort.get(rPriceSort.size()-1))[0]:"0.0"));
								rEntity.setSumHighestPrice(Double.parseDouble(RpriceList.get(rPriceSort.get(0))[1]!=null?RpriceList.get(rPriceSort.get(0))[1]:"0.0"));
								rEntity.setSumLowestPrice(Double.parseDouble(RpriceList.get(rPriceSort.get(rPriceSort.size()-1))[1]!=null?RpriceList.get(rPriceSort.get(rPriceSort.size()-1))[1]:"0.0"));
								rEntity.setTotalHighestTaxesPrice(Double.parseDouble(RpriceList.get(rPriceSort.get(0))[2]!=null?RpriceList.get(rPriceSort.get(0))[2]:"0.0"));
								rEntity.setTotalLowestTaxesPrice(Double.parseDouble(RpriceList.get(rPriceSort.get(rPriceSort.size()-1))[2]!=null?RpriceList.get(rPriceSort.get(rPriceSort.size()-1))[2]:"0.0"));
								
								entity.getReturnPlaneInfos().add(rEntity);//回程实体存入大实体
							}
						}
						//舱位关系
						if(cabinRelationEntitys.size()>0){
							entity.setCabinRelations(cabinRelationEntitys);
						}
						
						//最高最低价(去程)
						entity.setTotalHighestPrice(Double.parseDouble(GpriceList.get(gPriceSort.get(0))[0]!=null?GpriceList.get(gPriceSort.get(0))[0]:"0.0"));
						entity.setTotalLowestPrice(Double.parseDouble(GpriceList.get(gPriceSort.get(gPriceSort.size()-1))[0]!=null?GpriceList.get(gPriceSort.get(gPriceSort.size()-1))[0]:"0.0"));
						entity.setSumHighestPrice(Double.parseDouble(GpriceList.get(gPriceSort.get(0))[1]!=null?GpriceList.get(gPriceSort.get(0))[1]:"0.0"));
						entity.setSumLowestPrice(Double.parseDouble(GpriceList.get(gPriceSort.get(gPriceSort.size()-1))[1]!=null?GpriceList.get(gPriceSort.get(gPriceSort.size()-1))[1]:"0.0"));
						entity.setTotalHighestTaxesPrice(Double.parseDouble(GpriceList.get(gPriceSort.get(0))[2]!=null?GpriceList.get(gPriceSort.get(0))[2]:"0.0"));
						entity.setTotalLowestTaxesPrice(Double.parseDouble(GpriceList.get(gPriceSort.get(gPriceSort.size()-1))[2]!=null?GpriceList.get(gPriceSort.get(gPriceSort.size()-1))[2]:"0.0"));
						
						dataList.add(entity);
					}
				}
				
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		
		return dataList;
	}
	
	//排序
	public List<String> mapCompare (Map<String,String[]>  maps){
		List<String> priceSort=new ArrayList<String>();
		for(Entry<String, String[]>list:maps.entrySet()){
			priceSort.add(list.getKey());
		}
		Collections.sort(priceSort);
		return priceSort;
	}
	
	public void rPrices(List<CabinInfo> cabinList,Map<String,String[]> priceList){
		if(cabinList.size()>0){
			for(CabinInfo vo:cabinList){
				String totalPrice=vo.getTotalPrice()+"".split("\\.")[0];
				String tax =vo.getTaxPrice()+"".split("\\.")[0];
				String nakePrice=vo.getNakePirce()+"".split("\\.")[0];
				priceList.put(totalPrice, new String[]{totalPrice,nakePrice,tax});
				
				
				/*if(priceList.get(totalPrice) !=null){
					priceList.get("tax").add(tax);
				}else{
					List<String> t=new ArrayList<String>(); 
					t.add(tax);
					priceList.put("tax",t);
				}
				
				
				if(priceList.get("nakePrice") !=null){
					priceList.get("nakePrice").add(tax);
				}else{
					List<String> t=new ArrayList<String>(); 
					t.add(nakePrice);
					priceList.put("nakePrice", t);
				}
				
				
				if(priceList.get("totalPrice") !=null){
					priceList.get("totalPrice").add(tax);
				}else{
					List<String> t=new ArrayList<String>(); 
					t.add(totalPrice);
					priceList.put("totalPrice", t);
				}*/
			}
		}
		
	}
	
	//解析去程，回程段信息
	public List<FlightInfo> trRoute(JSONObject obj){/*
		List<FlightInfo> flithInfoList=new ArrayList<CanadaAdapter.FlightInfo>();
		JSONArray results=obj.getJSONArray("results");//对应的航班信息（共有N个航班）
		if(results.size()>0){
			for(int i=0;i<results.size();i++){
				JSONObject result=results.getJSONObject(i);
				flithInfoList=trLegInfo(result);
			}
		}
		return flithInfoList;
	*/
		return null;
	}
	
	
	//解析对应的航段信息
	public List<Object> trLegInfo(JSONObject result){
		List<Object> object=new ArrayList<Object>();
		List<FlightInfo> flithInfoList=new ArrayList<CanadaAdapter.FlightInfo>();
		List<CabinInfo> cabinInfoLists=new ArrayList<CanadaAdapter.CabinInfo>();
		JSONArray legs=result.getJSONArray("legs");
		Long duration =result.getLong("duration");//总飞行时间（毫秒）
		JSONArray fares=result.getJSONArray("fares");//价格信息
		cabinInfoLists=trPrice(fares);
		for(int i=0;i<legs.size();i++){
			FlightInfo vo=new FlightInfo();
			//有多段表示有中转
			JSONObject leg=legs.getJSONObject(i);
			String code=leg.getJSONObject("airline").getString("codes");//AC
			
			String flightType=leg.getString("aircraft");//飞机类型
			String flightNo =code+(leg.getInt("number")<100?"0"+leg.getInt("number"):(leg.getInt("number")<10?"00"+leg.getInt("number"):leg.getInt("number")));//航班号
			String startStr=leg.getString("departure").replace("T", " ");//出发时间
			String arrStr=leg.getString("arrival").replace("T", " ");//到达时间
			String agentName=null;//leg.getJSONObject("otherAirline") !=null?leg.getJSONObject("otherAirline").getString("name"):null;//代理商
			String fromPort=leg.getJSONObject("origin").getJSONObject("location").getString("codes");
			String fromPortName=leg.getJSONObject("origin").getJSONObject("location").getString("name");//出发机场名
			String toPortName=leg.getJSONObject("destination").getJSONObject("location").getString("name");//到达机场名
			String toPort=leg.getJSONObject("destination").getJSONObject("location").getString("codes");
			
			vo.setAgentName(agentName);
			vo.setEndTime(arrStr);
			vo.setFlightNo(flightNo);
			vo.setFlightType(flightType);
			vo.setFromAirport(fromPort);
			vo.setToAirport(toPort);
			vo.setStartTime(startStr);
			vo.setTendTime(arrStr);
			vo.setFromAirportName(fromPortName);
			vo.setToAirportName(toPortName);
			vo.setTstartTime(startStr);
			
			flithInfoList.add(vo);
		}
		if(flithInfoList.size()>0){
			flithInfoList.get(0).setFlightDuration(duration);
		}
		object.add(flithInfoList);
		object.add(cabinInfoLists);
		
		return object;
	}
	
	
	
	//解析航段舱位对应的价格信息
	public List<CabinInfo > trPrice(JSONArray fares){
		List<CabinInfo > cabinInfoList=new ArrayList<CanadaAdapter.CabinInfo>();
		if(fares.size()>0){
			for(int i=0;i<fares.size();i++){
				CabinInfo vo=new CabinInfo();
				JSONObject fare=fares.getJSONObject(i);
				JSONObject productObj=fare.getJSONObject("product").getJSONObject("0");
				//只取大舱位名称，不取小舱从位
				String cabName=CabinByNum.get(productObj.getString("segmentProduct")!=null?productObj.getString("segmentProduct"):null);
				JSONObject fareObj=fare.getJSONObject("fare").getJSONObject("0");
				String currency=fareObj.getString("currency");//货币单位
				Double totalPrice=fareObj.getDouble("boundTotalOriginal");//总价
				Double namkePrice=fareObj.getDouble("boundBase");//裸价
				vo.setNakePirce(namkePrice);
				vo.setCabinClass(cabName);
				vo.setCurrencyCode(currency);
				vo.setTotalPrice(totalPrice);
				vo.setTaxPrice(vo.getTotalPrice()-vo.getNakePirce());//税价
				cabinInfoList.add(vo);
			}
		}
		return cabinInfoList;
	}
	
	//旧版
	private List<Object> paraseToVoDI_2(Object fetchObject) throws Exception {
		if(fetchObject !=null && priceList.size()>0){
			List<Object> dataList = new ArrayList<Object>();
			List<String> allDatas=Lists.newArrayList();
			allDatas=(List<String>) fetchObject;
			for(int i=0;i<allDatas.size();i++){
				
//				getDatas//存入ID的list
				String idStr=getDatas.get(i);
				//去程ID系列
				String gidS=idStr.split("\\-")[0];
				//回程ID系列
				String ridS=idStr.split("\\-")[1];
				
				Map<String,String> gPriceStr=priceByid_1.get(gidS);//去程所有ID对应的价格
				Map<String,String> rPriceStr=priceByid_2.get(ridS);//回程所有ID对应的价格
				//去程裸价最高，最低
//				String gPrice=priceList.get(i)[0];
				String gHprice=sumPrics(gPriceStr)[0];
				String gLprice=sumPrics(gPriceStr)[1];
				//回程裸价最高，最低
				String rHprice=sumPrics(rPriceStr)[0];
				String rLprice=sumPrics(rPriceStr)[1];
				
				//税收最高，最低
				String taxHprice=sumPrics(taxById)[0];
				String taxLprice=sumPrics(taxById)[1];
				
				DoublePlaneInfoEntity entity=null;
				ReturnDoublePlaneInfoEntity rEntity=null;//回程实体
				
				String page=allDatas.get(i);
				Document doc=Jsoup.parse(page);
				List<Element> gInfos=doc.select("tr.on");//获取去程信息
				List<Element> rInfos=doc.select("tr.off");//获取回程信息
				String priceCode="";//货币单位
				//税价与总价  
				double sumPrices=0.0,sumToxP=0.0,totalPrices=0.0;//总价，税价，裸价总和
			//	sumPrices=Double.parseDouble(RegHtmlUtil.regStr(doc.select("th#qaid_spa_total_price_brief").first().text(),"\\W*(\\d*)\\."));//总价
			//	totalPrices=Double.parseDouble(doc.select("table.panelContainer").select("th.black").first().text());//往返裸价总价
				priceCode=doc.select("span.currencyCodeForAPI").first().text();
			//	String taxStr=null;
			//	taxStr=RegHtmlUtil.regStr(doc.select("table").toString(),"<th class=\"dots\"\\s*style=\"font-weight\\:\\s*normal\">\\s*<strong>\\s*(\\d*)");
			//	sumToxP=Double.parseDouble(taxStr !=null?taxStr:"0.0");
				
				int allStatus=0;
				if(gInfos.size()>0){//去程
					String flightNo=null,fromCity=null,fromCityName=null,toCity=null,toCityName=null,startTime=null,endTime=null,flightType=null;
					Long flightDuration=0L;
					for(int gS=0;gS<gInfos.size();gS++){//处理去程信息
						
						Element gi=gInfos.get(gS);
						flightNo=gi.select("div.flightNameCSS").first().text();
						String fromCityInfo=gi.select("div#qaid_spa_from_flight"+allStatus).first().text();
						fromCity=fromCityInfo.split("\\(")[1].replaceAll("\\)", "");
						fromCityName=fromCityInfo.split(",")[0];
						String toCityInfo=gi.select("div#qaid_spa_to_flight"+allStatus).first().text();
						toCity=toCityInfo.split("\\(")[1].replaceAll("\\)", "");
						toCityName=toCityInfo.split(",")[0];
						startTime=gi.select("td#qaid_spa_depart_time_flight"+allStatus).first().text();
						endTime=gi.select("td#qaid_spa_arrive_time_flight"+allStatus).first().text();
						String stop=gi.select("td#qaid_spa_stops_flight"+allStatus).first().text();//0表示不停留，1表示停留、
						flightType=gi.select("td#qaid_spa_aircraft_flight"+allStatus).first().text();
						//去程舱位信息
				//		String cabinStr=gi.select("td#qaid_spa_fare_type_flight"+allStatus).first().text();
						String useStr=null;
						useStr=RegHtmlUtil.regStr(gi.toString(),"<td>\\s*(\\d{1,2}<abbr\\s*title=\"小时\">hr</abbr>\\d{1,2})");
						String h=useStr!=null?RegHtmlUtil.regStr(useStr,"(\\d{1,2})"):null;
						String m=useStr!=null?RegHtmlUtil.regStr(useStr,"hr</abbr>(\\d{1,2})"):null;
						Long hl=h !=null?Long.parseLong(h)*60:0l;
						Long ml=m !=null?Long.parseLong(m):0l;
						flightDuration=(ml+hl );
						String BdateInfo=gi.select("td#qaid_spa_date_flight"+allStatus).first().text();//出发
						String detailD=RegHtmlUtil.regStr(BdateInfo,"(\\d{1,2}+\\-\\s*\\S*)");
						startTime=dateInfo(taskQueue.getFlightDate(),detailD,startTime);
						endTime=dateInfo(taskQueue.getFlightDate(),detailD,endTime);
						
						if(gS==0){//表示去程第一趟
							
							entity=PlaneInfoEntityBuilder.buildPlaneInfo(
									taskQueue, "AC","加拿大航空","加拿大航空公司", null, null, flightNo, null, null, null, flightType,DoublePlaneInfoEntity.class);
							entity.setStartTime(DateUtil.StringToDate("yyyy-MM-dd HH:mm:ss",startTime));
							entity.setFlightDuration(flightDuration*60*1000);
							//去程舱位信息
							for(Map.Entry<String, String> gCab:gPriceStr.entrySet()){
								CabinEntity cabinEntity=new CabinEntity();//去程舱位信息
								char lastNum=gCab.getKey().charAt(gCab.getKey().length()-1);
								String cName=CabinByNum.get(lastNum+"");
								if(cName.contains("商务")){
									cabinEntity.setCabinType("商务");
								}else{
									cabinEntity.setCabinType("经济");
								}
								cabinEntity.setProductName(cName);
								cabinEntity.setPrice(Double.parseDouble(gCab.getValue()));
								entity.getCabins().add(cabinEntity);
							}
					//		cabinEntity.setPrice(Double.parseDouble(gPrice));//把去程裸价存入第一段行程中
						}
//						cabinEntity.setProductName(cabinStr.split(",")[0]);
//						cabinEntity.setSubCabinName(cabinStr.split(",")[1].replaceAll(" ", ""));
						
						if(gInfos.size()>1){//含中转
							//组装(去程)中转信息
							TransitEntity trEntity=PlaneInfoEntityBuilder.buildTransitEntity(
									flightNo, null, "AC", "加拿大航空","加拿大航空公司", 
									fromCity, fromCityName, toCity, toCityName, flightType,TransitEntity.class);
							trEntity.setStartTime(DateUtil.StringToDate("yyyy-MM-dd HH:mm:ss",startTime));
							trEntity.setEndTime(DateUtil.StringToDate("yyyy-MM-dd HH:mm:ss",endTime));
						//	trEntity.setCabinName(cabinStr.split(",")[0]);
							entity.getTransits().add(trEntity);//增加中转信息到中转实体中
						}
						if(gS==gInfos.size()-1){//最后一趟
							entity.setEndTime(DateUtil.StringToDate("yyyy-MM-dd HH:mm:ss",endTime));
						}
						allStatus++;
					}
				}
				
				//处理回程信息
				if(rInfos.size()>0){//回程
					String RflightNo=null,RfromCity=null,RfromCityName=null,RtoCity=null,RtoCityName=null,RstartTime=null,RendTime=null,RflightType=null;
					Long RflightDuration=0L;
					
					for(int rS=0;rS<rInfos.size();rS++){//处理回程信息
						Element gi=rInfos.get(rS);
						if(gi.select("div.flightNameCSS").first().text().isEmpty()) continue;
						RflightNo=gi.select("div.flightNameCSS").first().text();
						String fromCityInfo=gi.select("div#qaid_spa_from_flight"+allStatus).first().text();
						RfromCity=fromCityInfo.split("\\(")[1].replaceAll("\\)", "");
						RfromCityName=fromCityInfo.split(",")[0];
						String toCityInfo=gi.select("div#qaid_spa_to_flight"+allStatus).first().text();
						RtoCity=toCityInfo.split("\\(")[1].replaceAll("\\)", "");
						RtoCityName=toCityInfo.split(",")[0];
						RstartTime=gi.select("td#qaid_spa_depart_time_flight"+allStatus).first().text();
						RendTime=gi.select("td#qaid_spa_arrive_time_flight"+allStatus).first().text();
						String stop=gi.select("td#qaid_spa_stops_flight"+allStatus).first().text();//0表示不停留，1表示停留、
						RflightType=gi.select("td#qaid_spa_aircraft_flight"+allStatus).first().text();
						//回程舱位信息
				//		String RcabinStr=gi.select("td#qaid_spa_fare_type_flight"+allStatus).first().text();
						String BdateInfo=gi.select("td#qaid_spa_date_flight"+allStatus).first().text();//出发
						String detailD=RegHtmlUtil.regStr(BdateInfo,"(\\d{1,2}+\\-\\s*\\S*)");
						RstartTime=dateInfo(taskQueue.getReturnGrabDate(),detailD,RstartTime);
						RendTime=dateInfo(taskQueue.getReturnGrabDate(),detailD,RendTime);
						
						String useStr=null;
						useStr=RegHtmlUtil.regStr(gi.toString(),"<td>\\s*(\\d{1,2}<abbr\\s*title=\"小时\">hr</abbr>\\d{1,2})");
						String h=useStr!=null?RegHtmlUtil.regStr(useStr,"(\\d{1,2})"):null;
						String m=useStr!=null?RegHtmlUtil.regStr(useStr,"hr</abbr>(\\d{1,2})"):null;
						Long hl=h !=null?Long.parseLong(h)*60:0l;
						Long ml=m !=null?Long.parseLong(m):0l;
						RflightDuration=(ml+hl );
						//回程舱位信息
//						ReturnCabinEntity rCabinE=PlaneInfoEntityBuilder.buildCabinInfo(
//								null, RcabinStr.split(",")[1].replaceAll(" ", ""), RcabinStr.split(",")[0], null, null, null, null, ReturnCabinEntity.class);
						if(rS==0){//组装回程实体
							rEntity=PlaneInfoEntityBuilder.buildPlaneInfo(
									taskQueue,"AC", "加拿大航空","加拿大航空公司", null,null, RflightNo, null, null,  null, RflightType, ReturnDoublePlaneInfoEntity.class);
							rEntity.setStartTime(DateUtil.StringToDate("yyyy-MM-dd HH:mm:ss",RstartTime));
							rEntity.setFlightDuration(RflightDuration);
							
							//回程舱位信息
							for(Map.Entry<String, String> gCab:rPriceStr.entrySet()){
								ReturnCabinEntity reEn=new ReturnCabinEntity();//去程舱位信息
								char lastNum=gCab.getKey().charAt(gCab.getKey().length()-1);
								String cName=CabinByNum.get(lastNum+"");
								if(cName.contains("商务")){
									reEn.setCabinType("商务");
								}else{
									reEn.setCabinType("经济");
								}
								reEn.setProductName(cName);
								reEn.setPrice(Double.parseDouble(gCab.getValue()));
								rEntity.getReturnCabins().add(reEn);
							}
						//	rCabinE.setPrice(Double.parseDouble(rPrice));//把回程裸价存入回程第一段行程中
						}
						
						if(rInfos.size()>1){//含中转信息
							//组装中转信息
							ReturnTransitEntity rTr=PlaneInfoEntityBuilder.buildTransitEntity(
									RflightNo, null, "AC", "加拿大航空","加拿大航空公司", 
									RfromCity, RfromCityName, RtoCity, RtoCityName, RflightType,ReturnTransitEntity.class);
							
							rTr.setStartTime(DateUtil.StringToDate("yyyy-MM-dd HH:mm:ss",RstartTime));
							rTr.setEndTime(DateUtil.StringToDate("yyyy-MM-dd HH:mm:ss",RendTime));
						//	rTr.setCabinName(RcabinStr.split(",")[0]);
							
							rEntity.getReturnTransits().add(rTr);
							
						}
						//回程舱位加入到回程实体中
					//	rEntity.getReturnCabins().add(rCabinE);
						if(rS==rInfos.size()-1){//回程最后一趟
							rEntity.setEndTime(DateUtil.StringToDate("yyyy-MM-dd HH:mm:ss",RendTime));
						}
						allStatus++;
					}
					entity.setTotalLowestPrice(Double.parseDouble(gLprice)+Double.parseDouble(rLprice));//去程裸价
					entity.setTotalHighestPrice(Double.parseDouble(gHprice)+Double.parseDouble(rHprice));
					entity.setSumHighestPrice(entity.getTotalHighestPrice()+Double.parseDouble(taxHprice));//去程总价
					entity.setSumLowestPrice(entity.getTotalLowestPrice()+Double.parseDouble(taxLprice));
					entity.setTotalHighestTaxesPrice(Double.parseDouble(taxHprice));//税价
					entity.setTotalLowestTaxesPrice(Double.parseDouble(taxLprice));
					entity.setCurrency(priceCode);
					//把回程信息放入
					rEntity.setTotalLowestPrice(Double.parseDouble(gLprice)+Double.parseDouble(rLprice));
					rEntity.setTotalHighestPrice(Double.parseDouble(gHprice)+Double.parseDouble(rHprice));
					rEntity.setSumHighestPrice(rEntity.getTotalHighestPrice()+Double.parseDouble(taxHprice));//回程最高总价
					rEntity.setSumLowestPrice(rEntity.getTotalLowestPrice()+Double.parseDouble(taxLprice));//回程最低总价
					rEntity.setTotalHighestTaxesPrice(Double.parseDouble(taxHprice));//税价
					rEntity.setTotalLowestTaxesPrice(Double.parseDouble(taxLprice));
					rEntity.setCurrency(priceCode);
					entity.getReturnPlaneInfos().add(rEntity);
				}
				dataList.add(entity); 
			}
			return dataList;
		}
		return null;
	}
	

	/**
	 * 处理出最总价格
	 * 
	*/
	public String[] sumPrics(Map<String,String>pricesMap){
		if(pricesMap.size()>0){
			String [] pricesStr=new String[2];
			double h=0.0,l=99999999.0;
			for(Map.Entry<String, String> map:pricesMap.entrySet()){
				if(Double.parseDouble(map.getValue())>h){
					h=Double.parseDouble(map.getValue());
				}
				if(Double.parseDouble(map.getValue())<l){
					l=Double.parseDouble(map.getValue());
				}
			}
			pricesStr[0]=h+"";
			pricesStr[1]=l+"";
			return pricesStr;
		}
		return null;
	}
	
	/**
	 * 处理日期
	 * time 14:10 +1 day
	*/
	public String dateInfo(String flightDateStr,String dateStr ,String time){
		String dateStrs="";
		if(flightDateStr !=null && !flightDateStr.equals("") && dateStr !=null && !dateStr.equals("")){
			String day=dateStr.split("\\-")[0];
			if(Integer.parseInt(day)<10 && day.length()<2) day="0"+day;
			String month=monthM.get(dateStr.split("\\-")[1]);
			String year=flightDateStr.substring(0,4);
			if(Integer.parseInt(month)<Integer.parseInt(flightDateStr.substring(5,7))){
				year=Integer.parseInt(year)+1+"";
			}
			
			if(time !=null && !time.equals("")){
				if(time.contains("day") || time.contains("+")){
					String days=RegHtmlUtil.regStr(time,"(\\+\\d*)");
					time=RegHtmlUtil.regStr(time,"(\\d{1,2}:\\d{1,2})");
					DateUtil.StringToDate("yyyy-MM-dd",year+"-"+month+"-"+day);
					Calendar date = Calendar.getInstance();
					SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
					date.setTime(DateUtil.StringToDate("yyyy-MM-dd",year+"-"+month+"-"+day));
					if(days.contains("+"))
						date.set(Calendar.DATE, date.get(Calendar.DATE) + Integer.parseInt(RegHtmlUtil.regStr(days,"\\W*([0-9]*)")));
					if(days.contains("-"))
						date.set(Calendar.DATE, date.get(Calendar.DATE) - Integer.parseInt(RegHtmlUtil.regStr(days,"\\W*([0-9]*)")));
					dateStrs=dft.format(date.getTime());
					dateStrs=dateStrs+" "+time+":00";
					return dateStrs;
				}
			}
			dateStrs=year+"-"+month+"-"+day+" "+time+":00";
			return dateStrs;
		}
		if(dateStr ==null || dateStr.equals("") && time !=null) return flightDateStr+" "+time+":00";
		
		return null;
	}
			
	
	
	
	/**
	 * 飞行总时间
	 * @return long
	*/
	public Long getFlightDuration(String dateStr){
		Long flightDuration=0l;
		if(dateStr !=null  && !dateStr.equals("")){
			if(dateStr.split("hr").length>1){
				flightDuration=Long.parseLong(dateStr.split("hr")[0])*60;
				flightDuration+=Long.parseLong(dateStr.split("hr")[1]);
			}else{
				flightDuration=Long.parseLong(dateStr);
			}
			
			return flightDuration*60*1000;//换成毫秒
		}
		return null;
	}
	
	//航班基础信息
	private class FlightInfo{
		private String TstartTime;//出发时间
		private String TendTime;//到达时间
		private String flightNo;//航班号
		private String startTime;//起飞时间
		private String endTime;//结束时间
		private String fromAirport;//起飞城市机场
		private String toAirport;//到达城市机场
		private String fromAirportName; 
		private String toAirportName;
		private String flightType;//飞机类型
		private Long stopTime;//停留时间
		private Long flightDuration;//飞行总时间
		private String agentName;//代理商名称
		public String getFlightNo() {
			return flightNo;
		}
		public void setFlightNo(String flightNo) {
			this.flightNo = flightNo;
		}
		public String getTstartTime() {
			return TstartTime;
		}
		public void setTstartTime(String tstartTime) {
			TstartTime = tstartTime;
		}
		public String getTendTime() {
			return TendTime;
		}
		public void setTendTime(String tendTime) {
			TendTime = tendTime;
		}
		public String getStartTime() {
			return startTime;
		}
		public void setStartTime(String startTime) {
			this.startTime = startTime;
		}
		public String getEndTime() {
			return endTime;
		}
		public void setEndTime(String endTime) {
			this.endTime = endTime;
		}
		public String getFromAirport() {
			return fromAirport;
		}
		public void setFromAirport(String fromAirport) {
			this.fromAirport = fromAirport;
		}
		public String getToAirport() {
			return toAirport;
		}
		public void setToAirport(String toAirport) {
			this.toAirport = toAirport;
		}
		
		public String getFromAirportName() {
			return fromAirportName;
		}
		public void setFromAirportName(String fromAirportName) {
			this.fromAirportName = fromAirportName;
		}
		public String getToAirportName() {
			return toAirportName;
		}
		public void setToAirportName(String toAirportName) {
			this.toAirportName = toAirportName;
		}
		public String getFlightType() {
			return flightType;
		}
		public void setFlightType(String flightType) {
			this.flightType = flightType;
		}
		public Long getStopTime() {
			return stopTime;
		}
		public void setStopTime(Long stopTime) {
			this.stopTime = stopTime;
		}
		public Long getFlightDuration() {
			return flightDuration;
		}
		public void setFlightDuration(Long flightDuration) {
			this.flightDuration = flightDuration;
		}
		public String getAgentName() {
			return agentName;
		}
		public void setAgentName(String agentName) {
			this.agentName = agentName;
		}
	}
		
	//价格信息
	private class CabinInfo{
		private String cabinClass;
		private Double totalPrice;//总价
		private Double nakePirce;//裸价
		private Double taxPrice;//税价
		private String currencyCode;//货币单位
		public String getCabinClass() {
			return cabinClass;
		}
		public void setCabinClass(String cabinClass) {
			this.cabinClass = cabinClass;
		}
		public Double getTotalPrice() {
			return totalPrice;
		}
		public void setTotalPrice(Double totalPrice) {
			this.totalPrice = totalPrice;
		}
		public Double getNakePirce() {
			return nakePirce;
		}
		public void setNakePirce(Double nakePirce) {
			this.nakePirce = nakePirce;
		}
		public Double getTaxPrice() {
			return taxPrice;
		}
		public void setTaxPrice(Double taxPrice) {
			this.taxPrice = taxPrice;
		}
		public String getCurrencyCode() {
			return currencyCode;
		}
		public void setCurrencyCode(String currencyCode) {
			this.currencyCode = currencyCode;
		}
	}
	
	
}
